package com.franklin.java.action.sql.run;

import com.franklin.java.api.mybatis.annotation.MyBatisAnnotation;
import com.franklin.java.api.mybatis.annotation.MyBatisAnnotations;
import com.franklin.java.api.mybatis.dom.franklin.MyMapper;
import com.franklin.java.api.mybatis.dom.utils.MapperUtils;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.xml.XmlTag;

import javax.swing.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * 处理Mapper中的@Select修饰的方法
 * @author Franklin
 * @since 2021/9/23 14:28
 */
public class MybatisMapperMethodSql extends MybatisSql<PsiMethod> {

    private MybatisXmlSql mybatisXmlSql;

    protected MybatisMapperMethodSql(PsiMethod sqlElement) {
        super(sqlElement);
        String selectValue = resolveSqlInAnnotation();
        PsiClass containingClass = sqlElement.getContainingClass();
        MyMapper mapper = MapperUtils.findMapper(sqlElement.getProject(),
            containingClass.getQualifiedName(),
            containingClass.getContainingFile().getVirtualFile().getPath()
        );

        XmlTag selectTag = mapper.getRootTag().createChildTag(getMapperMethodName(), "", selectValue, false);
        this.mybatisXmlSql = new MybatisXmlSql(selectTag);
        this.mybatisXmlSql.resolveParams();
    }

    @Override
    public List<MybatisParam> getParamList() {
        return this.mybatisXmlSql.getParamList();
    }

    @Override
    protected void resolveParams() {
        //do nothing
    }

    @Override
    public String resolveSqlFromForm(Map<String, JComponent> elExpressionComponentMap) {
        return this.mybatisXmlSql.resolveSqlFromForm(elExpressionComponentMap);
    }

    @Override
    public String getMapperMethodName() {
        return sqlElement.getName();
    }

    /**
     * select中的值<br>
     * @author Franklin
     * @since 2021/9/23 14:32
     * @param :
     * @return java.lang.String
     */
    private String resolveSqlInAnnotation() {
        PsiAnnotation psiAnnotation = sqlElement.getAnnotation(
            MyBatisAnnotations.get(MyBatisAnnotations.Select.class).getQualifiedName()
        );
        if (Objects.nonNull(psiAnnotation)) {
            return Optional.ofNullable(MyBatisAnnotations.parse(psiAnnotation))
                .map(MyBatisAnnotation::getValue)
                .orElse("");
        }
        return "";
    }
}
